home *** CD-ROM | disk | FTP | other *** search
- /**********************************************
-
- cache deiver Program
-
- 1991.04.15 make by Ken
-
- compile use : cl /Zp /Ze
-
- ***********************************************/
- #include <stdio.h>
- #include <dos.h>
- #include "defs.h"
-
- void farmemcpy(char far *p,char far *s,int n);
- uchar sum_calc(char far *p,ushort sz);
- void Dev_str_call(char far *ent,REQ far *req);
- void Dev_int_call(char far *ent);
- int DOS_allocmem(int size,unsigned *seg);
- void DOS_memfree(unsigned seg);
- DEVHED far *init_dmy_dev(void);
- DPB far *get_DPB(int dev);
- DPB far *link_DPB(void);
-
- ushort psp_seg;
- uchar Cache_off=FALSE;
- uchar hit_flg=0;
- uchar max_dev=0;
- ushort SecLen=0;
- uchar SecAlc=0;
- ushort DatSec=0;
- ushort MaxCls=0;
- char far *tmp=NULL;
- DEVHED far *dmy_dev=NULL;
- REQ dum_req;
-
- DPB far *dpb_ptr[MAX_DEV];
- REQ far *req_ptr[MAX_DEV];
- DEVHED far *dev_ent[MAX_DEV];
-
- SEC_PTR *use_tbl[MAX_HASH];
- SEC_PTR *lru_tbl[MAX_HASH];
- SEC_PTR tbl_buf[MAX_SEC];
-
- int serch(uchar dev,ulong sec,int md)
- {
- int hs;
- register SEC_PTR *bp;
- register SEC_PTR *tp;
-
- hs = HASH(sec);
-
- hit_flg = FALSE;
- tp = bp = lru_tbl[hs];
- while ( bp != NULL ) {
- if ( bp->dev == dev && bp->sec == sec ) {
- hit_flg = TRUE;
- break;
- } else if ( bp->next == NULL )
- break;
- tp = bp;
- bp = bp->next;
- }
- if ( tp != bp && (md != FALSE || hit_flg != FALSE) ) {
- tp->next = bp->next;
- bp->next = lru_tbl[hs];
- lru_tbl[hs] = bp;
- }
- return (bp == NULL ? 0:((uint)(bp) - (uint)(tbl_buf)) / sizeof(SEC_PTR));
- }
- void use_set(int pos)
- {
- int hs;
- SEC_PTR *pp;
- register SEC_PTR *bp;
- register SEC_PTR *tp;
-
- if ( pos >= MAX_SEC )
- return;
-
- pp = &(tbl_buf[pos]);
-
- if ( bp->dev == USE_DEV )
- return;
-
- hs = HASH(pp->sec);
- tp = bp = lru_tbl[hs];
- while ( bp != NULL ) {
- if ( bp == pp )
- break;
- tp = bp;
- bp = bp->next;
- }
-
- if ( bp == NULL )
- return;
-
- if ( tp != bp )
- tp->next = bp->next;
- else
- lru_tbl[hs] = bp->next;
-
- bp->dev = USE_DEV;
- bp->next = use_tbl[hs];
- use_tbl[hs] = bp;
- }
- void lru_set(int pos)
- {
- int hs;
- SEC_PTR *pp;
- register SEC_PTR *bp;
- register SEC_PTR *tp;
-
- if ( pos >= MAX_SEC )
- return;
-
- pp = &(tbl_buf[pos]);
-
- if ( pp->dev != USE_DEV )
- return;
-
- hs = HASH(pp->sec);
- tp = bp = use_tbl[hs];
- while ( bp != NULL ) {
- if ( bp == pp )
- break;
- tp = bp;
- bp = bp->next;
- }
-
- if ( bp == NULL )
- return;
-
- if ( tp != bp )
- tp->next = bp->next;
- else
- use_tbl[hs] = bp->next;
-
- bp->dev = FRE_DEV;
- bp->next = lru_tbl[hs];
- lru_tbl[hs] = bp;
- }
- void flush_tbl(int max_sec)
- {
- int i,hs;
- register SEC_PTR *bp;
-
- for ( i = 0 ; i < MAX_HASH ; i++ )
- use_tbl[i] = lru_tbl[i] = NULL;
-
- bp = tbl_buf;
- for ( i = 0 ; i < max_sec && i < MAX_SEC ; i++ ) {
- hs = HASH(i);
- bp->sec = i;
- bp->dev = USE_DEV;
- bp->next = use_tbl[hs];
- use_tbl[hs] = bp;
- bp++;
- }
- }
- void flush_dev(uchar dev)
- {
- int i;
- register SEC_PTR *bp;
-
- for ( i = 0 ; i < MAX_HASH ; i++ ) {
- bp = lru_tbl[i];
- while ( bp != NULL ) {
- if ( bp->dev == dev )
- bp->dev = FRE_DEV;
- bp = bp->next;
- }
- }
- }
- void Device_call(uchar dev,REQ far *req)
- {
- union {
- char far *p;
- short s[2];
- } pp;
-
- pp.p = (char far *)(dev_ent[dev]);
-
- pp.s[0] = dev_ent[dev]->str_ent;
- Dev_str_call(pp.p,req);
-
- pp.s[0] = dev_ent[dev]->int_ent;
- Dev_int_call(pp.p);
- }
- int Read_sub(ushort sec,char far *buf)
- {
- dum_req.len = 19;
- dum_req.unit = dpb_ptr[0]->UnitNum;
- dum_req.cmds = 4;
- dum_req.stat = 0;
- dum_req.md_id = dpb_ptr[0]->MedId;
- dum_req.x.rdwt.buff = buf;
- dum_req.x.rdwt.sect = sec;
- dum_req.x.rdwt.count = 1;
- Device_call(0,(REQ far *)&dum_req);
- return ((dum_req.stat & 0x8000) != 0 ? ERR:FALSE);
- }
- int Write_sub(ushort sec,char far *buf)
- {
- dum_req.len = 19;
- dum_req.unit = dpb_ptr[0]->UnitNum;
- dum_req.cmds = 8;
- dum_req.stat = 0;
- dum_req.md_id = dpb_ptr[0]->MedId;
- dum_req.x.rdwt.buff = buf;
- dum_req.x.rdwt.sect = sec;
- dum_req.x.rdwt.count = 1;
- Device_call(0,(REQ far *)&dum_req);
- return ((dum_req.stat & 0x8000) != 0 ? ERR:FALSE);
- }
- void Cache_set(uchar dev,ushort sec,char far *buf)
- {
- int rt;
- ushort sz,pos;
- ulong lsec;
-
- sz = dpb_ptr[dev]->SecLen;
- lsec = (ulong)sec * ((sz + SecLen -1) / SecLen);
-
- while ( (int)sz > 0 ) {
- if ( (pos = serch(dev,lsec,TRUE)) == 0 )
- break;
-
- if ( sz < SecLen ) {
- farmemcpy(tmp,buf,sz);
- rt = Write_sub(pos,tmp);
- } else
- rt = Write_sub(pos,buf);
-
- if ( rt != FALSE ) {
- use_set(pos);
- continue;
- }
-
- tbl_buf[pos].dev = dev;
- tbl_buf[pos].sec = lsec;
- tbl_buf[pos].sum = sum_calc(buf,sz);
-
- buf += SecLen;
- sz -= SecLen;
- lsec++;
- }
- }
- int Cache_chk(uchar dev,ushort sec,char far *buf)
- {
- int rt;
- ushort sz,pos;
- ulong lsec;
-
- sz = dpb_ptr[dev]->SecLen;
- lsec = (ulong)sec * ((sz + SecLen - 1) / SecLen);
-
- while ( (int)sz > 0 ) {
- if ( (pos = serch(dev,lsec,FALSE)) == 0 || hit_flg == FALSE )
- return FALSE;
-
- if ( sz < SecLen ) {
- rt = Read_sub(pos,tmp);
- farmemcpy(buf,tmp,sz);
- } else
- rt = Read_sub(pos,buf);
-
- if ( rt != FALSE || tbl_buf[pos].sum != sum_calc(buf,sz) ) {
- use_set(pos);
- continue;
- }
-
- buf += SecLen;
- sz -= SecLen;
- lsec++;
- }
-
- return TRUE;
- }
- void cls_lru_set(ushort cls)
- {
- int i;
- ushort sec;
-
- if ( cls < 2 || cls >= MaxCls )
- return;
-
- sec = (cls - 2) * SecAlc + DatSec;
-
- for ( i = 0 ; i < SecAlc ; i++ )
- lru_set(sec++);
- }
- void cls_use_set(ushort cls)
- {
- int i;
- ushort sec;
-
- if ( cls < 2 || cls >= MaxCls )
- return;
-
- sec = (cls - 2) * SecAlc + DatSec;
-
- for ( i = 0 ; i < SecAlc ; i++ )
- use_set(sec++);
- }
- void FAT_chk(int no,char far *p)
- {
- int i,n,max;
-
- no *= SecLen;
- n = (no + 2) / 3;
- i = n * 3 - no;
- max = SecLen - 3;
-
- while ( i < max ) {
-
- if ( (*((short far *)(&p[i])) & 0x0FFF) == 0 )
- cls_lru_set(n * 2);
- else
- cls_use_set(n * 2);
-
- if ( (*((short far *)(&p[i+1])) & 0xFFF0) == 0 )
- cls_lru_set(n * 2 + 1);
- else
- cls_use_set(n * 2 + 1);
-
- n++;
- i += 3;
- }
- }
- void Device_entry(uchar dev)
- {
- int i;
- DPB far *dp;
- REQ far *rp;
- BPB far *bp;
- ushort sec;
- char far *buf;
-
- dp = dpb_ptr[dev];
- rp = req_ptr[dev];
-
- if ( dev == 0 ) { /* Cache Buffer Device */
- switch(rp->cmds) {
- case 2: /* Build BPB */
- Device_call(dev,rp);
- bp = rp->x.build.bpb;
-
- if ( (rp->stat & 0x8000) != 0 || SecLen < bp->SecLen ) {
- Cache_off = TRUE;
- break;
- }
-
- SecLen = bp->SecLen;
- SecAlc = bp->SecAlc + 1;
- DatSec = bp->ResSec +
- bp->DirEnt * 32 / bp->SecLen +
- bp->FatLen * bp->FatSec;
- MaxCls = (bp->MaxSec - DatSec) / SecAlc;
-
- flush_tbl(bp->MaxSec);
- Cache_off = FALSE;
- break;
-
- case 4: /* Read */
- case 8: /* Write */
- case 9: /* Write & Verify */
- Device_call(dev,rp);
- if ( (rp->stat & 0x8000) != 0 )
- break;
-
- sec = rp->x.rdwt.sect;
- buf = rp->x.rdwt.buff;
- i = rp->x.rdwt.count;
-
- while ( i-- > 0 ) {
- if ( sec >= dp->ResSec && (sec - dp->ResSec) < dp->FatSec )
- FAT_chk(sec - dp->ResSec,buf);
- else
- use_set(sec);
- sec++;
- buf += dp->SecLen;
- }
- break;
-
- case 80: /* Ext Command Get Mode */
- rp->x.ext.mode = Cache_off;
- rp->x.ext.max_dev = max_dev;
- rp->x.ext.dpb_ptr = (DPB far *)dpb_ptr;
- rp->x.ext.lru_tbl = (SEC_PTR far *)lru_tbl;
- rp->x.ext.use_tbl = (SEC_PTR far *)use_tbl;
- rp->stat = 0x0100;
- break;
-
- case 81: /* Ext Command Exit Cache */
- for ( i = 0 ; i < max_dev ; i++ )
- dpb_ptr[i]->DevEnt = dev_ent[i];
- rp->x.quit.psp_seg = psp_seg;
- rp->stat = 0x0100;
- break;
-
- default:
- Device_call(dev,rp);
- break;
- }
-
- } else {
- if ( Cache_off != FALSE ) {
- Device_call(dev,rp);
- return;
- }
-
- switch(rp->cmds) {
- case 1: /* Media Check */
- Device_call(dev,rp);
- if ( (rp->stat & 0x8000) != 0 || rp->x.chk.now_sts <= 0 )
- flush_dev(dev);
- break;
-
- case 2: /* Build BPB */
- Device_call(dev,rp);
- flush_dev(dev);
- break;
-
- case 4: /* Read */
- sec = rp->x.rdwt.sect;
- buf = rp->x.rdwt.buff;
- i = rp->x.rdwt.count;
-
- while ( i-- > 0 ) {
- if ( Cache_chk(dev,sec,buf) == FALSE )
- goto CACHE_SET;
- sec++;
- buf += dp->SecLen;
- }
- rp->stat = 0x0100;
- break;
-
- case 8: /* Write */
- case 9: /* Write & Verify */
- CACHE_SET:
- sec = rp->x.rdwt.sect;
- buf = rp->x.rdwt.buff;
- i = rp->x.rdwt.count;
-
- Device_call(dev,rp);
- if ( (rp->stat & 0x8000) != 0 ) {
- flush_dev(dev);
- break;
- }
-
- while ( i-- > 0 ) {
- Cache_set(dev,sec,buf);
- sec++;
- buf += dp->SecLen;
- }
- break;
-
- default:
- Device_call(dev,rp);
- if ( (rp->stat & 0x8000) != 0 )
- flush_dev(dev);
- break;
- }
- }
- }
- int Dev_set(int dev,int unit)
- {
- DPB far *dp;
-
- if ( dev == 0 )
- dp = get_DPB(unit);
- else {
- dp = link_DPB();
- while ( (long)dp != 0xFFFFFFFFL ) {
- if ( dp->DrvNum == unit )
- break;
- dp = dp->NxtDPB;
- }
- }
-
- if ( (long)dp == 0xFFFFFFFFL )
- return ERR;
-
- dpb_ptr[dev] = dp;
- dev_ent[dev] = dpb_ptr[dev]->DevEnt;
- dpb_ptr[dev]->DevEnt = dmy_dev + dev;
-
- dmy_dev[dev].next = dev_ent[dev]->next;
- dmy_dev[dev].dev_sts = dev_ent[dev]->dev_sts;
- dmy_dev[dev].res[0] = dev_ent[dev]->res[0];
-
- return FALSE;
- }
- int setup(char *para)
- {
- static int i;
- int dev=0;
- char *p;
- union {
- char far *p;
- short s[2];
- } sp;
-
- dmy_dev = init_dmy_dev();
-
- i = *(para++);
- para[i] = '\0';
- while ( *para != '\0' ) {
- while ( *para != '\0' && *para <= ' ' ) para++;
- if ( (*para >= 'a' && *para <= 'z') ||
- (*para >= 'A' && *para <= 'Z') ) {
- if ( Dev_set(dev++,(*para & 0xDF) - 'A') ) {
- msg_disp("デバイスを確認できません\n\r$");
- return 1;
- }
- }
- while ( *para != '\0' && *para > ' ' ) para++;
- }
-
- if ( dev == 0 ) {
- msg_disp("use: CACHE <Buffer Device> <Cache Device....>\n\r$");
- return 1;
- }
-
- max_dev = dev;
- SecLen = dpb_ptr[0]->SecLen;
- SecAlc = dpb_ptr[0]->SecAlc + 1;
- DatSec = dpb_ptr[0]->DatSec;
- MaxCls = dpb_ptr[0]->MaxCls;
- flush_tbl(MaxCls * SecAlc);
- Cache_off = FALSE;
-
- if ( DOS_allocmem((SecLen+15U)/16,(unsigned *)&i) != FALSE ) {
- msg_disp("セクタバッファメモリを確保できませんでした\n\r$");
- goto ERROR;
- }
-
- FP_OFF(tmp) = 0;
- FP_SEG(tmp) = i;
-
- for ( i = 0 ; i < dpb_ptr[0]->FatSec ; i++ ) {
- if ( Read_sub(dpb_ptr[0]->ResSec + i,tmp) == FALSE )
- FAT_chk(i,tmp);
- }
-
- DOS_memfree(FP_SEG(tmp));
-
- msg_disp("キャッシュが設定されました!!\n\r$");
-
- return 0;
-
- ERROR:
- for ( i = 0 ; i < max_dev ; i++ )
- dpb_ptr[i]->DevEnt = dev_ent[i];
-
- return 1;
- }